#!/usr/bin/python

"""
    File:       TestCase.py
    Brief:      testcase
    Author:     Xu Qiang
    Version:    1.0
    Date:       2017 - 4 - 18    
"""


import Static
import Functional
import ServiceControl
from ServiceControl import startAllServices, stopAllServices
from Error import *
from Log import Log, LogI, LogD, LogE, LogW


class TestResultState( object ):
    PASS = "ok"
    FAILED = "not ok"
    BLOCKED = "blocked"
    NOTRUN = "skipped"
    ERROR = "error"

class TestCase( object ):
    def __init__( self, name = None, logFileName = None, tapFileName = None ):
        if name == None:
            self.m_name = self.__class__.__name__
        else:
            self.m_name = name
        if logFileName == None:
            self.m_logFileName = self.m_name + ".log"
        else:
            self.m_logFileName = logFileName + ".log"
            
        self.m_stepList = []    
        
    def run( self ):
        LogD.write( self.m_name + "[begin]" )
        self.m_result = []
        self.before_run()
        self.precondition()
        self.body()
        self.after_run()
        LogD.write( self.m_name + "[end]" )

    def precondition( self ):
        pass

    def before_run( self ):
        if ServiceControl.getService( "browser" ) == None:
            startAllServices()
        try:
#             Functional.restoreDefault()
            Functional.loginWebpage()
        except Exception, e:
            Functional.capturePIC("ERROR.jpg")
            LogE.write( "%s after_run failed by %s" % ( self.m_name, str( e ) ) )

    def after_run( self ):
        try:
            stopAllServices()
        except Exception, e:
            Functional.capturePIC("ERROR.jpg")
            LogE.write( "%s after_run failed by %s" % ( self.m_name, str( e ) ) )
            
    def AddStep( self, step ):
        self.m_stepList.append( step )

    def on_exception( self, e ):
        if isinstance( e, KeyboardInterrupt ):
            LogD.write( self.m_name + "break by keyboard interrupt." )
            stopAllServices()
            exit( 1 )

        LogE.write( self.m_name + " cause exception " + str( e ) )

    def body( self ):
        LogI.write( "[Extend] TestCase %s [Begin]" % self.m_name )
        #add step describe     
        rtn = True    
        for step in self.m_stepList:
            LogI.write( "[Extend] step %s [Begin]" % step.__name__ )             
            try:
                step()
            except Exception, e:
                rtn = False
                LogI.write( "[Extend] ERROR" )
                LogD.write( "[Extend] step fail by %s." % str( e ) )
#                 Functional.capturePIC(step.__name__ +"_ERROR.jpg")
                try:
                    Functional.capturePIC(step.__name__ +"_ERROR.jpg")
                except Exception,e:
                    print e
            except KeyboardInterrupt:
                rtn = False
                LogI.write( "[Extend] interrupt by user." )
                Functional.capturePIC(step.__name__ +"_ERROR.jpg")
                break
            LogI.write( "[Extend] step %s [End]" % step.__name__ )
        LogI.write( "[Extend] TestCase %s [End]" % self.m_name )
        return rtn


class DataDrivedTestCase( TestCase ):
    def __init__( self, name = None, logFileName = None, tapFileName = None, dataInput = None ):
        if dataInput == None:
            dataInput = Static.WebTestDir + "\\input\\default.ini"
        else:
            dataInput = Static.WebTestDir + "\\input\\" + dataInput
        from Configure import iniManager
        self._data = iniManager( dataInput )
        self._default = iniManager( Static.WebTestDir + "\\input\\default.ini" )
        super( DataDrivedTestCase, self ).__init__( name, logFileName, tapFileName )

    def getData( self, data ):
        res = self._data.__getattr__( data )
        if res == None:
            res = self._default.__getattr__( data )
        return res


class TestSet:
    def __init__( self, name ):
        self.m_name = name
        self.m_testCaseList = []
        self.m_testSetList = []

    def addTestSet( self, testSet ):
        assert isinstance( testSet, TestSet )
        self.m_testSetList.append( testSet )

    def addTestCase( self, testCase ):
        assert isinstance( testCase, TestCase )
        self.m_testCaseList.append( testCase )

    def _changeOutput( self ):
        self.m_originalOutput = Static.outputPath
        import os
        if not os.path.exists( Static.outputPath + "\\" + self.m_name ):
            os.makedirs( Static.outputPath + "\\" + self.m_name )
        Static.outputPath = Static.outputPath + "\\" + self.m_name + "\\"
        self.m_tapOutput = Static.TAPoutputPath
        if not os.access( self.m_tapOutput , os.F_OK ):
            os.makedirs( self.m_tapOutput )
#         allFiles = os.listdir( self.m_tapOutput )
#         for file in allFiles:
#             if ".tap" in file:
#                 try:
#                     os.remove( self.m_tapOutput + file )
#                 except:
#                     pass
        
        
    def _restoreOutput( self ):
        Static.outputPath = self.m_originalOutput

    def before_run( self ):
        if ServiceControl.getService( "browser" ) == None:
            startAllServices()
        try:
            Functional.loginWebpage()
        except Exception, e:
            LogE.write( "%s after_run failed by %s" % ( self.m_name, str( e ) ) )

    def precondition( self ):
        pass

    def after_run( self ):
        try:
            stopAllServices()
        except Exception, e:
            LogE.write( "%s after_run failed by %s" % ( self.m_name, str( e ) ) )

    def run( self ):
        self._changeOutput()
        LogD.write( "%s [begin]" % self.m_name )
        self.before_run()
        self.precondition()
        for set in self.m_testSetList:
            set.run()
        for case in self.m_testCaseList:
            try:
                if(case.body()):
                    pass
                else:
                    self.after_run()
                    self.before_run()
            except Exception, e:
                self.after_run()
                self.before_run()

        self.after_run()
        LogD.write( "%s [end]" % self.m_name )
        self._restoreOutput()
